package com.crrcdt.meeting.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.crrcdt.meeting.entity.Employee;
import com.crrcdt.meeting.entity.Meeting;
import com.crrcdt.meeting.entity.Meetingparticipants;
import com.crrcdt.meeting.entity.Meetingroom;
import com.crrcdt.meeting.mapper.EmployeeMapper;
import com.crrcdt.meeting.service.EmployeeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.crrcdt.meeting.service.MeetingService;
import com.crrcdt.meeting.service.MeetingparticipantsService;
import com.crrcdt.meeting.service.MeetingroomService;
import com.crrcdt.meeting.utils.ExcelImportUtil;
import com.crrcdt.meeting.utils.currentUser;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.jxls.common.Context;
import org.jxls.transform.Transformer;
import org.jxls.transform.poi.PoiTransformer;
import org.jxls.util.JxlsHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author liujun
 * @since 2020-09-20
 */
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService, UserDetailsService {
    @Autowired
    EmployeeService employeeService;
    @Autowired
    HttpSession session;
    @Autowired
    MeetingparticipantsService meetingparticipantsService;
    @Autowired
    MeetingService meetingService;
    @Autowired
    MeetingroomService meetingroomService;
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {// 通过用户名查询用户
        Employee employee = employeeService.getOne(new QueryWrapper<Employee>().eq("username", s));

        // 放入session
        session.setAttribute("loginUser", employee);

        //创建一个新的UserDetails对象，最后验证登陆的需要
        UserDetails userDetails = null;
        if (employee != null) {
            System.out.println("未加密："+employee.getPassword());
            String BCryptPassword = new BCryptPasswordEncoder().encode(employee.getPassword());
            // 登录后会将登录密码进行加密，然后比对数据库中的密码，数据库密码需要加密存储！（这里很恶心！）
            String password = employee.getPassword();

            //创建一个集合来存放权限
            Collection<GrantedAuthority> authorities = getAuthorities(employee);
            Boolean enabled=employee.getStatus().equals("1");
            //实例化UserDetails对象
            userDetails = new org.springframework.security.core.userdetails.User(s, BCryptPassword,
                    enabled,
                    true,
                    true,
                    true, authorities);
        }
        return userDetails;
    }
    private Collection<GrantedAuthority> getAuthorities (Employee employee){
        final String role = employee.getRole();
        List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
        authList.add(new SimpleGrantedAuthority("ROLE_" +("1".equals(role) ? "管理员":"普通用户")));
        return authList;
    }

    @Override
    public void exportAllEmpoyee(HttpServletResponse response, HttpServletRequest request) throws IOException {
        //得到当前对象
        final Employee currentEmployee = currentUser.getCurrentEmployee(request);
        final List<Meetingparticipants> meetingparticipants = meetingparticipantsService.list(new QueryWrapper<Meetingparticipants>().eq("employeeid", currentEmployee.getEmployeeid()));
        //得到会议ids
        final List<Integer> meetingIds = meetingparticipants.stream().map(Meetingparticipants::getMeetingid).collect(Collectors.toList());
        //得到我的会议集合
        final List<Meeting> meetingList = meetingService.list(new QueryWrapper<Meeting>().in("meetingid",meetingIds));
       //给meetingList中设置会议室名称和预定者名称
        if(meetingList!=null){
            meetingList.stream().forEach(meeting -> {
                final String roomname = meetingroomService.list(new QueryWrapper<Meetingroom>().eq("roomid", meeting.getRoomid())).get(0).getRoomname();
                final List<Employee> employeeList = employeeService.list(new QueryWrapper<Employee>().eq("employeeid", meeting.getReservationistid()));
                meeting.setReservationistName(employeeList.get(0).getEmployeename());
                meeting.setRoomName(roomname);
            });
        }
        //获取模板
        final InputStream is = this.getInputStream();
        //returnMap
        final HashMap<String, Object> returnMap = new HashMap<>();
        returnMap.put("meetingList",meetingList);
        //将文件放置到客户端下载
        this.setResponse(response);
        //excel表格导出
        exportExcel(is, response.getOutputStream(), returnMap);
    }

    @Override
    @Transactional
    public Boolean importMeetings(MultipartFile file) {
        final Workbook wb = ExcelImportUtil.init(file);
        final Sheet sheet = wb.getSheetAt(0);
        final int rows = sheet.getLastRowNum();
        final ArrayList<Meeting> meetings = new ArrayList<>();
        for (int i = 1; i <=rows ; i++) {
            final Row row = sheet.getRow(i);
            this.setEmployees(meetings,row);
        }
        final boolean res = meetingService.saveBatch(meetings);
        return res;
    }
    public void setEmployees(List<Meeting> meetings, Row row){
        final Meeting meeting = new Meeting();
        final String meetingname = ExcelImportUtil.convertCell2String(row.getCell(0));
        final String roomid = ExcelImportUtil.convertCell2String(row.getCell(1));
        final String reservationistid = ExcelImportUtil.convertCell2String(row.getCell(2));
        final String numberofparticipants = ExcelImportUtil.convertCell2String(row.getCell(3));
        final String starttime = ExcelImportUtil.convertCell2String(row.getCell(4));
        final String endtime = ExcelImportUtil.convertCell2String(row.getCell(5));
        final String reservationtime = ExcelImportUtil.convertCell2String(row.getCell(6));
        final String canceledtime = ExcelImportUtil.convertCell2String(row.getCell(7));
        final String description = ExcelImportUtil.convertCell2String(row.getCell(8));
        final String status = ExcelImportUtil.convertCell2String(row.getCell(9));
        final String canceledreason = ExcelImportUtil.convertCell2String(row.getCell(10));
        meeting.setMeetingname(meetingname);
        meeting.setRoomid(Integer.valueOf(roomid));
        meeting.setReservationistid(Integer.valueOf(reservationistid));
        meeting.setNumberofparticipants(Integer.valueOf(numberofparticipants));
        meeting.setStarttime(DateUtil.parse(starttime));
        meeting.setEndtime(DateUtil.parse(endtime));
        meeting.setReservationtime(DateUtil.parse(reservationtime));
        meeting.setCanceledreason(canceledreason);
        meeting.setCanceledtime(DateUtil.parse(canceledtime));
        meeting.setDescription(description);
        meeting.setStatus(status);
        meetings.add(meeting);
    }

    private InputStream getInputStream() throws FileNotFoundException {
//        final URL url = this.getClass().getClassLoader().getResource("user/user.xlsx");
        final URL url = this.getClass().getClassLoader().getResource("meeting/meetings.xlsx");
        return new FileInputStream(url.getFile());
    }
    private void setResponse(final HttpServletResponse response) {
        response.reset();
        response.setContentType("application/octet-stream; charset=utf-8");
        response.setHeader("Content-Disposition", "meetings; filename=" + "xlsExport.xls");
    }
    public static void exportExcel(final InputStream is, final OutputStream os, final Map<String, Object> model) throws IOException {
        final Context context = PoiTransformer.createInitialContext();
        if (model != null) {
            for (final String key : model.keySet()) {
                context.putVar(key, model.get(key));
            }
        }
        final JxlsHelper jxlsHelper = JxlsHelper.getInstance();
        final Transformer transformer = jxlsHelper.createTransformer(is, os);
        //必须要这个，否者表格函数统计会错乱
        jxlsHelper.setUseFastFormulaProcessor(false).processTemplate(context, transformer);

    }
}
